package org.javarosa.view;

import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Ticker;

import org.javarosa.core.api.IView;
import org.javarosa.core.services.mesh4j.extensions.SyncEngineService;

public class ConsoleScreen extends List implements CommandListener, IView {

	private static final Object SEMAPHORE = new Object();
	private static final int REFRESH_INTERVAL = 6000;
	
	public static final String LABEL_EXIT = "Exit";
	public static final String LABEL_CLEAN = "Clean";
	public static final String LABEL_REFRESH = "Refresh";
	public static final String LABEL_VIEW_SMS = "View Sms";
	public static final String LABEL_VIEW_PROTOCOL = "View Protocol";
	public static final String LABEL_VIEW_ALL = "View All";
	
	public static final String LABEL_TICKER = "Sms console waiting for messages - Mesh4X Midlet version -    ";

	// MODEL VARIABLES
    private Command exitCommand;
    private Command cleanCommand;
    private Command refreshCommand;
    private Command viewSmsCommand;
    private Command viewProtocolCommand;
    private Command viewAllCommand;
    
	private Image imageBegin;
	private Image imageEnd;
	private Image imageSend;
	private Image imageReceive;
	private Image imageReSend;
	private Image imageError;
	private Image imageProcess;
	private Image imageCancel;
	private Image imageUnexpected;
	
	private boolean viewSms = false;
	private boolean viewProtocol = true;
	
	private int lastItemsSize = 0;
	
	private IConsoleActionListener consoleAction;
	private Timer timer;
	private int counter = 0;
    
	// BUSINESS METHODS
    
	public ConsoleScreen (IConsoleActionListener consoleAction) {
		super("Console", List.IMPLICIT);
		
		this.consoleAction = consoleAction;
		
		this.exitCommand = new Command(LABEL_EXIT, Command.EXIT, 1);
		this.refreshCommand = new Command(LABEL_REFRESH, Command.SCREEN, 2);
		this.viewAllCommand = new Command(LABEL_VIEW_ALL, Command.SCREEN, 3);
		this.viewSmsCommand = new Command(LABEL_VIEW_SMS, Command.SCREEN, 4);
		this.viewProtocolCommand = new Command(LABEL_VIEW_PROTOCOL, Command.SCREEN, 5);
		this.cleanCommand = new Command(LABEL_CLEAN, Command.SCREEN, 6);
				
		this.setCommandListener(this);
		
		timer = new Timer();
		timer.schedule(new TimerTask () {
			public void run () {
					counter += REFRESH_INTERVAL;
					refreshConsole();
				}
			}, 
			REFRESH_INTERVAL, 
			REFRESH_INTERVAL);
		
		createView();
	}

	public void createView() {
		
		this.deleteAll();
		
		this.addCommand(exitCommand);
		this.addCommand(refreshCommand);
		this.addCommand(viewAllCommand);
		this.addCommand(viewSmsCommand);
		this.addCommand(viewProtocolCommand);
		this.addCommand(cleanCommand);
		
		this.imageBegin = createImage(12, 12, 255, 255, 0);
		this.imageEnd = createImage(12, 12, 255, 255, 0);
		this.imageSend = createImage(12, 12, 0, 0, 255);
		this.imageReceive = createImage(12, 12, 0, 255, 0);
		this.imageUnexpected = createImage(12, 12, 0, 0, 0);
		this.imageError = createImage(12, 12, 255, 0, 0);
		this.imageProcess = createImage(12, 12, 255, 0, 255);
		this.imageCancel = createImage(12, 12, 255, 0, 100);
		this.imageReSend = createImage(12, 12, 255, 100, 100);
    	
		this.setTicker(new Ticker(LABEL_TICKER));
	}
	
	public void setItems(Vector<String> items) {
		if(lastItemsSize != items.size()){
			this.lastItemsSize = items.size();
			
			this.deleteAll();
			String message;
			String textToShow;
			for (int i = 0; i < items.size(); i++) {
				message = items.elementAt(i);
				textToShow = i + " - " + message;
				if(message.startsWith("Protocol Error")){
					this.append(textToShow, this.imageError);
				} else if(this.viewProtocol && message.startsWith("Begin")){
					this.append(textToShow, this.imageBegin);
				} else if(this.viewProtocol && message.startsWith("Cancel")){
					this.append(textToShow, this.imageCancel);
				} else if (this.viewProtocol && message.startsWith("End")){
					this.append(textToShow, this.imageEnd);
				}else if(this.viewProtocol && message.startsWith("Process")){
					this.append(textToShow, this.imageProcess);
				}else if(this.viewProtocol && message.startsWith("Re-send")){
					this.append(textToShow, this.imageReSend);
				}else if(this.viewProtocol && message.startsWith("Ask")){
					this.append(textToShow, this.imageReSend);
				} else if (this.viewSms && message.startsWith("Send")){
					this.append(textToShow, this.imageSend);
				} else if (this.viewSms && message.startsWith("Receive")){
					this.append(textToShow, this.imageReceive);
				} else if(message.startsWith("Sms Error")){
					this.append(textToShow, this.imageError);
				} else if(message.startsWith("Unexpected")){
					this.append(textToShow, this.imageUnexpected);
				}
			}
		}
		//this.setFitPolicy(TEXT_WRAP_ON);
		//this.setFont(i, Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL));
	}
	
	private Image createImage(int w, int h, int r, int g, int b) {
		Image res = Image.createImage(w, h);
		Graphics gc = res.getGraphics();
		gc.setColor(r, g, b);
		gc.fillRect(0, 0, w, h);
		return res;
	}

	public void setViewAll() {
		this.viewSms = true;
		this.viewProtocol = true;
		this.lastItemsSize = 0;
	}
	
	public void setViewSms() {
		this.viewSms = true;
		this.viewProtocol = false;
		this.lastItemsSize = 0;
	}

	public void setViewProtocol() {
		this.viewSms = false;
		this.viewProtocol = true;
		this.lastItemsSize = 0;
	}

	
	public void commandAction(Command c, Displayable d) {
		if(d == this){	
			if(c.getLabel() == ConsoleScreen.LABEL_EXIT){
				this.timer.cancel();
				this.timer = null;
				this.consoleAction.exit();
			} else if(c.getLabel() == ConsoleScreen.LABEL_CLEAN){
				SyncEngineService.cleanConsole();
			} else if(c.getLabel() == ConsoleScreen.LABEL_REFRESH){
				refreshConsole();
			} else if(c.getLabel() == ConsoleScreen.LABEL_VIEW_ALL){
				this.setViewAll();
				refreshConsole();
			} else if(c.getLabel() == ConsoleScreen.LABEL_VIEW_SMS){
				this.setViewSms();
				refreshConsole();
			} else if(c.getLabel() == ConsoleScreen.LABEL_VIEW_PROTOCOL){
				this.setViewProtocol();
				refreshConsole();
			}
		}
	}

	public void refreshConsole() {
		synchronized (SEMAPHORE) {
			this.setItems(SyncEngineService.getConsoleItems());
		}
	}

	public Object getScreenObject() {
		return this;
	}
}
